﻿/*****************************************************************************
 
 Use of Ext is under the Ext JS license, for more information, 
 please visit http://extjs.com/products/license.php page. 
  
 You should confirm that you have read, understood and accept ethical criteria listed. 
 If not, see <http://www.mvcnext.com/license/>.
  
 Version: 1.0.0.0
 Website: http://www.mvcnext.com/
 
 Copyright (c) Yoganand R. All rights reserved.
 For continued development and updates, visit http://yogsbreath.net
 
 ******************************************************************************/
using System;
using System.Collections.Generic;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.IO;
using System.Reflection;
using System.Collections;
using System.Web.UI;
using System.Text;

namespace MVCnExt.Web.UI.Ext
{
    /// <summary>
    /// Standard contentContainer used for grouping form fields.
    /// </summary>
    [Description("Standard contentContainer used for grouping form fields.")]
    public class ExtFieldSet : ExtComponent  
    {
        private List<ExtComponent> _items = new List<ExtComponent>();
        private List<ConfigItem> _defaults = new List<ConfigItem>();
        private List<ScriptReference> _references = new List<ScriptReference>();

        public override List<ScriptReference> GetScriptReferences()
        {
            return base.GetScriptReferences();
        }

        public override IList<ScriptDescriptor> GetScriptDescriptors()
        {
            IList<ScriptDescriptor> list = base.GetScriptDescriptors();

            ScriptControlDescriptorBase desc = (ScriptControlDescriptorBase)list[0];

            desc.Type = "Ext.form.FieldSet";

            String[] properties = new String[]{
                "autoHeight", "autoWidth", "checkboxName", "checkboxToggle", "itemCls", "labelWidth", "title", "style"         
            };

            Type component = typeof(ExtFieldSet);

            foreach (String property in properties)
            {
                PropertyInfo i = component.GetProperty(property);

                if (i == null)
                    throw new InvalidOperationException(String.Format("Property not found, 'ExtFieldSet.{0}'", property));

                Object value = i.GetValue(this, null);

                if (value == null)
                {
                    continue;
                }

                if (!(value is String))
                    desc.AddPropertyBase(property, value);
                else
                    desc.AddPropertyBase(property, String.Format("'{0}'", value));
            }

            //add items
            if (items.Count != 0)
            {
                // build items list
                StringBuilder itemList = new StringBuilder("[");

                for (int i = 0; i < items.Count; i++)
                {
                    // add comma between items
                    if (i != 0)
                    {
                        itemList.Append(",");
#if DEBUG
                        itemList.AppendLine("\t\t\t");
#endif
                    }

                    // get the item script
                    IList<ScriptDescriptor> descriptors = items[i].GetScriptDescriptors();

                    // get the items's list of script dependencies
                    List<ScriptReference> references = items[i].GetScriptReferences();

                    // make sure the script dependencies are registered
                    _references.AddRange(references);

                    // write the item's config to the list
                    itemList.Append(((ExtScriptControlDescriptor)descriptors[0]).WriteScript(ScriptType.NewOnly));
                }

                itemList.Append("]");

                desc.AddPropertyBase("items", itemList);
            }

            //add defaults
            if (defaults.Count != 0)
            {
                StringBuilder config = new StringBuilder("{");

                for (int i = 0; i < defaults.Count; i++)
                {
                    if (i != 0)
                    {
                        config.Append(",");
#if DEBUG
                        config.AppendLine();
#endif
                    }
                    config.AppendFormat("{0} : '{1}'", defaults[i].name, defaults[i].value);
                }

                config.Append("}");

#if DEBUG
                config.AppendLine();
#endif

                desc.AddPropertyBase("defaults", config);
            }

            return list;
        }

        #region Public Properties

        [NotifyParentProperty(true)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public virtual List<ExtComponent> items
        {
            get
            {
                return _items;
            }
        }

        [NotifyParentProperty(true)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public List<ConfigItem> defaults
        {
            get
            {
                return _defaults;
            }
        }

        public String title { get; set; }

        /// <summary>
        /// True to render a checkbox into the fieldset frame just in front of the legend (defaults to false). The fieldset will be expanded or collapsed when the checkbox is toggled.
        /// </summary>
        [Description("True to render a checkbox into the fieldset frame just in front of the legend (defaults to false). The fieldset will be expanded or collapsed when the checkbox is toggled.")]
        public Boolean? autoHeight { get; set; }

        /// <summary>
        /// True to render a checkbox into the fieldset frame just in front of the legend (defaults to false). The fieldset will be expanded or collapsed when the checkbox is toggled.
        /// </summary>
        [Description("True to render a checkbox into the fieldset frame just in front of the legend (defaults to false). The fieldset will be expanded or collapsed when the checkbox is toggled.")]
        public Boolean? autoWidth { get; set; }

        /// <summary>
        /// True to render a checkbox into the fieldset frame just in front of the legend (defaults to false). The fieldset will be expanded or collapsed when the checkbox is toggled.
        /// </summary>
        [Description("True to render a checkbox into the fieldset frame just in front of the legend (defaults to false). The fieldset will be expanded or collapsed when the checkbox is toggled.")]
        public String checkboxName { get; set; }

        /// <summary>
        /// True to render a checkbox into the fieldset frame just in front of the legend (defaults to false). The fieldset will be expanded or collapsed when the checkbox is toggled.
        /// </summary>
        [Description("True to render a checkbox into the fieldset frame just in front of the legend (defaults to false). The fieldset will be expanded or collapsed when the checkbox is toggled.")]
        public String checkboxToggle { get; set; }

        /// <summary>
        /// A css class to apply to the x-form-items of fields. This property cascades to child containers.
        /// </summary>
        [Description("A css class to apply to the x-form-items of fields. This property cascades to child containers.")]
        public Boolean? itemCls { get; set; }

        /// <summary>
        /// The width of labels. This property cascades to child containers.
        /// </summary>
        [DefaultValue("75")]
        [Description("The width of labels. This property cascades to child containers.")]
        public Unit? labelWidth { get; set; }       

        #endregion
    }
}
